package org.hackystat.ambientdevice.server;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;
import org.hackystat.ambientdevice.device.AmbientAction;
import org.hackystat.ambientdevice.trigger.HackystatTrigger;

/**
 * Class that extends TimerTask to periodically check the triggers state and update the AmbientOrb's
 * state accordingly.
 * 
 * @author Shaoxuan Zhang
 */
public class TriggerActionTimerTask extends TimerTask implements Serializable {

  /**
   * default serial.
   */
  private static final long serialVersionUID = 1L;
  /** The interval between two state checking. */
  private long interval = 6000;
  /** A list of actions that will take place when all triggers are active. */
  private List<AmbientAction> negativeActionList = new ArrayList<AmbientAction>();
  /** A list of actions that will take place when some triggers are inactive. */
  private List<AmbientAction> positiveActionList = new ArrayList<AmbientAction>();
  /** A list of triggers that determine if the action will take place or not. */
  private List<HackystatTrigger> triggerList = new ArrayList<HackystatTrigger>();
  /** The current state of the triggers of this task. */
  private boolean currentState = false;
  /** flag that tell if the task is running for the first time.  */
  private boolean firstTime = true;
  /** name of this task. */
  private String name = null;

  /**
   * @return the Interval
   */
  public long getInterval() {
    return this.interval;
  }

  /**
   * @param interval the interval to set
   */
  public void setInterval(long interval) {
    this.interval = interval;
  }

  /**
   * Method that will be called when this timertask is awoke.
   */
  @Override
  public void run() {
    boolean newState = true;
    System.out.println("Updating Triggers state.");
    try {
      for (HackystatTrigger trigger : this.triggerList) {
        if (!trigger.getState()) {
          newState = false;
          break;
        }
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      newState = false;
    }
    System.out.println("New state = " + newState);
    if (newState == this.currentState && !this.firstTime) {
      //only take the action once when state change.
      return;
    }
    this.firstTime = false;
    this.currentState = newState;
    if (newState) {
      System.out.println("All Triggers are active, changing devices' state.");
      for (AmbientAction action : this.positiveActionList) {
        action.act();
      }
    }
    else if (this.negativeActionList.size() > 0) {
      System.out.println("Some Triggers are inactive, changing devices' state.");
      for (AmbientAction action : this.negativeActionList) {
        action.act();
      }
    }
  }

  /**
   * @param negativeActionList the negativeActionList to set
   */
  public void setNegativeActionList(List<AmbientAction> negativeActionList) {
    this.negativeActionList = negativeActionList;
  }

  /**
   * @return the negativeActionList
   */
  public List<AmbientAction> getNegativeActionList() {
    return negativeActionList;
  }

  /**
   * @param positiveActionList the positiveActionList to set
   */
  public void setPositiveActionList(List<AmbientAction> positiveActionList) {
    this.positiveActionList = positiveActionList;
  }

  /**
   * @return the positiveActionList
   */
  public List<AmbientAction> getPositiveActionList() {
    return positiveActionList;
  }

  /**
   * @param triggerList the triggerList to set
   */
  public void setTriggerList(List<HackystatTrigger> triggerList) {
    this.triggerList = triggerList;
  }

  /**
   * @return the triggerList
   */
  public List<HackystatTrigger> getTriggerList() {
    return triggerList;
  }

  /**
   * @param name the name to set
   */
  public void setName(String name) {
    this.name = name;
  }

  /**
   * @return the name
   */
  public String getName() {
    return name;
  }

}
